package com.spring.test.factory;

import org.springframework.beans.factory.FactoryBean;

/**
	 下面测试往factory-bean里填FactoryBean的实现类,xml不报错的条件是
	 1) FactoryBean后面不带泛型
	 2) getObjectType()返回null
 */
@Deprecated
public class CarErrorFactoryBean implements FactoryBean {
/*	private String name;
	private Integer age;

	public void setName(String name) {
		this.name = name;
	}

	public void setAge(Integer age) {
		this.age = age;
	}*/

	private InstanceCarFactory instanceCarFactory;

	public void setInstanceCarFactory(InstanceCarFactory instanceCarFactory) {
		this.instanceCarFactory = instanceCarFactory;
	}

	@Override
	public Object getObject() throws Exception {
		//org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod#458
		//factoryBean = this.beanFactory.getBean(factoryBeanName)
		//用来返回factory-bean指定的factoryBean,然后调用它的factory-method

		//错误写法: 获取userError对象,调用getObject方法返回User对象,User对象没有getObject方法,报错
		//return new User(name,age);
		//*********************************************
		/*
		 	<bean id="userError" class="com.spring.test.factory.UserErrorFactoryBean">
				<property name="name" value="jack"></property>
				<property name="age" value="19"></property>
			</bean>
			<bean id="car5" factory-bean="userError" factory-method="getObject">

			</bean>
		 */
		//********************************************


		//正确写法: 获取userError对象,调用getObject方法返回一个实例工厂bean,然后定义一个与该实例工厂bean的工厂方法声明相同的方法即可,
		//factory-method属性指向该方法(不需要实现,只是为了xml不报错,实际调的还是实例工厂bean的工厂方法)

		//org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod#464
		//[1]获取类型,为InstanceCarFactory
		//factoryClass = factoryBean.getClass();
		//org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod#521~526
		//[2]找到与factory-method定义的名称相同的方法
		/*
		 	Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
			for (Method candidate : rawCandidates) {
				if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
					candidates.add(candidate);
				}
			}
		*/
		//org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod#614
		//[3]经过一堆判断得到要使用的factoryMethod
		//factoryMethodToUse = candidate;

		//org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod#688
		//[4]调用该方法
		//bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
		//return bw;

		//*********************************************
		/*
			<bean id="userError" class="com.spring.test.factory.UserErrorFactoryBean"></bean>
			<bean id="car5" factory-bean="userError" factory-method="getCar">
				<constructor-arg value="ford"></constructor-arg>
			</bean>
		 */
		InstanceCarFactory instanceCarFactory = new InstanceCarFactory();
		setInstanceCarFactory(instanceCarFactory);
		return instanceCarFactory;
	}

	@Override
	public Class<?> getObjectType() {
		return null;
	}

	@Override
	public boolean isSingleton() {
		return true;
	}

	//把InstanceCarFactory的工厂方法声明复制过来(不需要实现,只是让xml不报错,实际调的还是InstanceCarFactory实例的getCar)
	public Car getCar(String brand) {
		return null;
	}
}
